import 'package:http_parser/http_parser.dart';

import '../common/test_page.dart';

class AuthenticationChallengeTestPage extends TestPage{
  AuthenticationChallengeTestPage(super.title) {
    group('parse', () {
      _singleChallengeTests(AuthenticationChallenge.parse);
    });

    group('parseHeader', () {
      group('with a single challenge', () {
        _singleChallengeTests((challenge) {
          final challenges = AuthenticationChallenge.parseHeader(challenge);
          expect(challenges, 1);
          return challenges.single;
        });
      });

      test('AuthenticationChallenge.parseHeader(scheme1 realm=fblthp, scheme2 realm=asdfg)',
              () {
        final challenges = AuthenticationChallenge.parseHeader(
            'scheme1 realm=fblthp, scheme2 realm=asdfg');
        expect(challenges, 2);
        expect(challenges.first.scheme, 'scheme1');
        expect(challenges.first.parameters, {'realm': 'fblthp'});
        expect(challenges.last.scheme, 'scheme2');
        expect(challenges.last.parameters, {'realm': 'asdfg'});
      });

      test('AuthenticationChallenge.parseHeader(scheme1 realm=fblthp, foo=bar, scheme2 realm=asdfg, baz=bang)',
              () {
        final challenges = AuthenticationChallenge.parseHeader(
            'scheme1 realm=fblthp, foo=bar, scheme2 realm=asdfg, baz=bang');
        expect(challenges, 2);

        expect(challenges.first.scheme, 'scheme1');
        expect(challenges.first.parameters, {'realm': 'fblthp', 'foo': 'bar'});

        expect(challenges.last.scheme, 'scheme2');
        expect(challenges.last.parameters, {'realm': 'asdfg', 'baz': 'bang'});
      });
    });
  }

  void _singleChallengeTests(
      AuthenticationChallenge Function(String challenge) parseChallenge) {
    test('${parseChallenge.toString()}(scheme realm=fblthp)', () {
      final challenge = parseChallenge('scheme realm=fblthp');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp'});
    });

    test('${parseChallenge.toString()}(scheme realm=fblthp, foo=bar, baz=qux)', () {
      final challenge = parseChallenge('scheme realm=fblthp, foo=bar, baz=qux');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp', 'foo': 'bar', 'baz': 'qux'});
    });

    test('${parseChallenge.toString()}(scheme realm="fblthp, foo=bar", baz="qux")', () {
      final challenge = parseChallenge('scheme realm="fblthp, foo=bar", baz="qux"');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp, foo=bar', 'baz': 'qux'});
    });

    test('${parseChallenge.toString()}(ScHeMe realm=fblthp)', () {
      final challenge = parseChallenge('ScHeMe realm=fblthp');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp'});
    });

    test('${parseChallenge.toString()}(scheme ReAlM=fblthp)', () {
      final challenge = parseChallenge('scheme ReAlM=fblthp');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm', 'fblthp'});
    });

    test("${parseChallenge.toString()}(scheme realm=FbLtHp)", () {
      final challenge = parseChallenge('scheme realm=FbLtHp');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm', 'FbLtHp'});
      expect(challenge.parameters, {'realm', 'fblthp'});
    });

    test('${parseChallenge.toString()}(scheme realm = fblthp, foo = bar)', () {
      final challenge = parseChallenge(
          '  scheme\t \trealm\t = \tfblthp\t, \tfoo\t\r\n =\tbar\t');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp', 'foo': 'bar'});
    });

    test('${parseChallenge.toString()}(scheme realm=fblthp, , foo=bar)', () {
      final challenge = parseChallenge('scheme realm=fblthp, , foo=bar');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp', 'foo': 'bar'});
    });

    test('${parseChallenge.toString()}(scheme , realm=fblthp, foo=bar,)', () {
      final challenge = parseChallenge('scheme , realm=fblthp, foo=bar,');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp', 'foo': 'bar'});
    });

    test('${parseChallenge.toString()}(scheme realm=fblthp, foo=bar, ,)', () {
      final challenge = parseChallenge('scheme realm=fblthp, foo=bar, ,');
      expect(challenge.scheme, 'scheme');
      expect(challenge.parameters, {'realm': 'fblthp', 'foo': 'bar'});
    });

    test('${parseChallenge.toString()}(scheme)', () {
      expect(() => parseChallenge('scheme'), '');
    });

    test('${parseChallenge.toString()}(scheme realm)  (scheme realm=)  (scheme realm, foo=bar)', () {
      expect(() => parseChallenge('scheme realm'), '');
      expect(() => parseChallenge('scheme realm='), '');
      expect(
              () => parseChallenge('scheme realm, foo=bar'), '');
    });

    test('${parseChallenge.toString()}(scheme"(/t)""(/r/n/t)"realm)', () {
      expect(() => parseChallenge('scheme\trealm'), '');
      expect(() => parseChallenge('scheme\r\n\trealm='), '');
    });

    test('${parseChallenge.toString()}(scheme realm=fblthp, foo=bar baz)', () {
      expect(
              () => parseChallenge('scheme realm=fblthp foo'), '');
      expect(() => parseChallenge('scheme realm=fblthp, foo=bar baz'),
          '');
    });
  }

}